﻿using MaterialDemo.DataEntity;
using MaterialDemo.DataEntity.Entities;
using MaterialDemo.IService.IPermission;
using MaterialDemo.Model.UserDTO;
using MaterialDemo.Utility;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MaterialDemo.Service.Permission
{
    public class UserService : IUserService
    {
        #region 构造函数注入
        private readonly ILogger<UserService> _logger;
        private readonly DbContext _dbContext;
        public UserService(ILogger<UserService> logger, DbContext dbcontext)
        {
            _logger = logger;
            _dbContext = dbcontext;
        }
        #endregion
        public int Add(UserInput inputEntity)
        {
            UserInfo entity = new UserInfo
            {

                DelFlag = 0,
                AddTime = DateTime.Now,
                PassWord = MD5Helper.EncryptString("123"),
                DelTime = null,

                DepartmentId = inputEntity.DepartmentId,
                Email = inputEntity.Email,
                PhoneNum = inputEntity.PhoneNum,
                Sex = inputEntity.Sex,
                UserId = inputEntity.UserId,
                UserName = inputEntity.UserName,
            };
            _dbContext.Set<UserInfo>().Add(entity);
            return _dbContext.SaveChanges();
        }

        public bool CheckRepeat(string value)
        {
            if (_dbContext.Set<UserInfo>().Where(u => u.UserId == value.Trim()).Count() > 0)
            {
                return true; //查看用户是否已存在，如果存在返回true
            }
            else
            {
                return false;
            }
        }

        public bool ForbidUser(int id, string flag)
        {
            UserInfo entity = _dbContext.Set<UserInfo>().Where(u => u.Id == id).FirstOrDefault();
            if (entity != null)
            {
                if (flag == "true")
                {
                    entity.DelFlag = 0;//表示开启
                    _dbContext.Set<UserInfo>().Attach(entity);
                    _dbContext.Set<UserInfo>().Update(entity);
                    if (_dbContext.SaveChanges() > 0)
                    {
                        return true;
                    }
                }
                else
                {
                    entity.DelFlag = 1;//表示禁用
                    _dbContext.Set<UserInfo>().Attach(entity);
                    _dbContext.Set<UserInfo>().Update(entity);
                    if (_dbContext.SaveChanges() > 0)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public List<UserOutput> LoadEntities(int id)
        {
            var linq = (from a in _dbContext.Set<UserInfo>().Where(u => u.Id == id)
                        join b in _dbContext.Set<DepartmentInfo>() on a.DepartmentId equals b.DepartmentId into join_a
                        from c in join_a.DefaultIfEmpty()
                        select new UserOutput
                        {
                            AddTime = a.AddTime,
                            DelFlag = a.DelFlag,
                            DepartmentId = a.DepartmentId,
                            DepartmentName = c.DepartmentName,
                            Email = a.Email,
                            Id = a.Id,
                            PhoneNum = a.PhoneNum,
                            Sex = a.Sex,
                            UserId = a.UserId,
                            UserName = a.UserName,
                        });
            return linq.ToList();
        }

        public List<UserOutput> LoadPagesEntities(int pageIndex, int pageSize, out int count, string selectInfo)
        {
            _dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;//暂时设置不追踪查询实体，优化效率
            //1.先获取管理员基本信息
            IQueryable<UserInfo> user_iquery;
            if (selectInfo == null)
            {
                //.给count赋值
                count = _dbContext.Set<UserInfo>().Count();
                user_iquery = _dbContext.Set<UserInfo>().OrderBy(u => u.Id).Skip((pageIndex - 1) * pageSize).Take(pageSize);

            }
            else
            {
                //.给count赋值
                count = _dbContext.Set<UserInfo>().Where(u => u.UserName.Contains(selectInfo)).Count();
                user_iquery = _dbContext.Set<UserInfo>().Where(u => u.UserName.Contains(selectInfo)).OrderBy(u => u.Id).Skip((pageIndex - 1) * pageSize).Take(pageSize);
            }
           

            //2.联表
            IQueryable<DepartmentInfo> dp_iquery = _dbContext.Set<DepartmentInfo>();//获取部门信息
            IQueryable<RUserInfoRoleInfo> r_iquery = _dbContext.Set<RUserInfoRoleInfo>().Where(u => u.Id > 0);//获取角色中间表
            IQueryable<RoleInfo> role_iquery = _dbContext.Set<RoleInfo>().Where(u => u.DelFlag == 0);//获取未被禁用的角色         
            IQueryable<UserOutput> linq = (from a in user_iquery
                                           join b in dp_iquery on a.DepartmentId equals b.DepartmentId into join_a
                                           from c in join_a.DefaultIfEmpty()
                                           join d in r_iquery on a.UserId equals d.UserId into join_b
                                           from e in join_b.DefaultIfEmpty()
                                           join f in role_iquery on e.RoleId equals f.RoleId into join_c
                                           from g in join_c.DefaultIfEmpty()
                                           select new UserOutput
                                           {
                                               Id = a.Id,
                                               UserId = a.UserId,
                                               UserName = a.UserName,
                                               PhoneNum = a.PhoneNum,
                                               AddTime = a.AddTime,
                                               DelFlag = a.DelFlag,
                                               Sex = a.Sex,
                                               RoleName = g.RoleName,
                                               DepartmentId = a.DepartmentId,
                                               DepartmentName=c.DepartmentName,
                                           });
            //3.分组
            #region 方式1：使用linq分组，ef6.0适用但是ef core不适用
            //var grplinq = (from p in linq
            //               group p by new
            //               {
            //                   p.ID,
            //                   p.UserID,
            //                   p.UserName,
            //                   p.PhoneNum,
            //                   p.AddTime,
            //                   p.DelFlag,
            //                   p.Sex,
            //                   p.DepartmentID,

            //               }).AsEnumerable().Select(grp =>
            //             new AdminInfoOutput
            //             {
            //                 ID = grp.Key.ID,
            //                 UserID = grp.Key.UserID,
            //                 UserName = grp.Key.UserName,
            //                 PhoneNum = grp.Key.PhoneNum,
            //                 AddTime = grp.Key.AddTime,
            //                 DelFlag = grp.Key.DelFlag,
            //                 Sex = grp.Key.Sex,
            //                 RoleName = String.Join(",", grp.Select(x => x.RoleName).ToArray()),
            //                 DepartmentID = grp.Key.DepartmentID,
            //             }).ToList();

            #endregion

            #region 方式2：自己分组合并

            List<UserOutput> list = new List<UserOutput>();
            var a88 = linq.ToList();
            foreach (var item_a in linq)
            {
                bool isAdded = false;//判断新集合是否已经添加过相同userId的依据，
                foreach (var item_b in list)
                {
                    if (item_b.UserId == item_a.UserId)
                    {
                        isAdded = true;
                        item_b.RoleName += "," + item_a.RoleName;//如果已经添加过相同userId，则在角色信息列拼接字符串
                    }
                }
                if (isAdded == false)
                {
                    list.Add(item_a);//如果新集合没有添加过userId，则添加数据
                }
            }

            #endregion
            _dbContext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;//重新设置为追踪查询实体
            return list;
        }

        public bool RePwd(int id)
        {
            UserInfo entity = _dbContext.Set<UserInfo>().Where(u => u.Id == id).FirstOrDefault();
            if (entity != null)
            {
                entity.PassWord = MD5Helper.EncryptString("123");
                _dbContext.Set<UserInfo>().Attach(entity);
                _dbContext.Set<UserInfo>().Update(entity);
                if (_dbContext.SaveChanges() > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
        public int Update(UserInput inputEntity)
        {
            //先查，再改需要改的
            UserInfo entity = _dbContext.Set<UserInfo>().Where(u => u.UserId == inputEntity.UserId).FirstOrDefault();
            if (entity != null)
            {
                entity.DepartmentId = inputEntity.DepartmentId;
                entity.PhoneNum = inputEntity.PhoneNum;
                entity.Sex = inputEntity.Sex;
                entity.UserName = inputEntity.UserName;
                entity.Email = inputEntity.Email;
            }
            _dbContext.Set<UserInfo>().Attach(entity);
            _dbContext.Set<UserInfo>().Update(entity);
            return _dbContext.SaveChanges();
        }

        public bool Delete(int id)
        {
            UserInfo entity = _dbContext.Set<UserInfo>().Where(u => u.Id == id).FirstOrDefault();
            _dbContext.Set<UserInfo>().RemoveRange(entity);
            return _dbContext.SaveChanges() > 0;
        }
    }
}
